package com.sz.biz.logistics.base.service.impl;

import com.sz.biz.common.constants.ErrorCodes;
import com.sz.biz.common.constants.ModuleNames;
import com.sz.biz.common.base.entity.Country;
import com.sz.biz.logistics.base.entity.Ship;
import com.sz.biz.logistics.base.entity.ShippingCompany;
import com.sz.biz.common.base.service.AreaManager;
import com.sz.biz.logistics.base.service.ShipService;
import com.sz.biz.logistics.base.service.ShippingCompanyService;
import com.sz.biz.logistics.base.dto.ShippingCompanyDto;
import com.sz.common.base.cache.EntityCache;
import com.sz.common.base.constants.UserActions;
import com.sz.common.base.dao.DaoSupport;
import com.sz.common.base.dao.ParamData;
import com.sz.common.base.dto.I18nDto;
import com.sz.common.base.dto.QResultDto;
import com.sz.common.base.dto.QueryParams;
import com.sz.common.base.dto.ResultDto;
import com.sz.common.base.exception.Exceptions;
import com.sz.common.base.service.AbstractService;
import com.sz.common.base.utils.CollectionUtils;
import com.sz.common.base.utils.EntityUtils;
import com.sz.common.core.service.PrincipalLogUtils;
import com.sz.common.core.service.PrincipalUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Function: 航运公司ShippingCompanyServiceImpl <br>
 * Author: wentao.chang <br>
 * Date: 2017-08-04 15:41:00
 */
@Service("shippingCompanyService")
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class ShippingCompanyServiceImpl extends AbstractService implements ShippingCompanyService {

    @Autowired
    AreaManager areaManager;
    @Autowired
    ShipService shipService;

    @Resource(name = "daoSupport")
    private DaoSupport dao;

    @Override
    public void refreshCache() {
        EntityCache.clearNamespace("ShippingCompanyMapper");
    }

    @Override
    public int save(ShippingCompanyDto ShippingCompanyDto) {
        ShippingCompany ship = new ShippingCompany();
        EntityUtils.copyPropertiesIgnoreNull(ShippingCompanyDto, ship);
        // 检查数据不能重复
        checkCode(ship.getCode(), null);

        dao.save("ShippingCompanyMapper.insert", ship);
        // 保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("ADD_SHIPPINGCOMPANY", ship);
        PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_SHIPPINGCOMPANY, UserActions.ADD, "新建航运公司",
                dataBackup);
        return ship.getId();
    }

    @Override
    public int update(Integer id, ShippingCompanyDto ShippingCompanyDto) {
        //检查是否被船引用

        ShippingCompany shipExist = findSimpleById(id);
        if (shipExist.getIsDeleted()) {
            throw Exceptions.bizException(ErrorCodes.ERROR_MODEL_HAS_DELETED, id);
        }
        ShippingCompany ship = new ShippingCompany();
        EntityUtils.copyPropertiesIgnoreNull(ShippingCompanyDto, ship);
        // 检查数据不能重复
        checkCode(ship.getCode(), id);

        ship.setId(id);
        dao.update("ShippingCompanyMapper.update", ship);
        // 保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("UPDATE_SHIPPINGCOMPANY", ship);
        PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_SHIPPINGCOMPANY, UserActions.UPDATE, "修改航运公司",
                dataBackup);
        return id;
    }

    private void checkName(String name, Integer id) {
        Map<String, Object> map = new HashMap<>();
        map.put("name", name);
        map.put("id", id);
        ShippingCompany shipExist = (ShippingCompany) dao.findForObject("ShippingCompanyMapper.checkName", map);
        if (shipExist != null) {
            throw Exceptions.bizException(ErrorCodes.ERROR_BIZ_SHIPPINGCOMPANY_NAME_EXIST);
        }
    }

    private void checkCode(String code, Integer id) {
        Map<String, Object> map = new HashMap<>();
        map.put("code", code);
        map.put("id", id);
        ShippingCompany shipExist = (ShippingCompany) dao.findForObject("ShippingCompanyMapper.checkCode", map);
        if (shipExist != null) {
            throw Exceptions.bizException(ErrorCodes.ERROR_BIZ_SHIPPINGCOMPANY_CODE_EXIST);
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void deleteByIds(List<Integer> ids) {
        for(Integer id:ids){

            //检查是否被船引用
            List<Ship> ships = shipService.findByCompanyId(id);
            if (!CollectionUtils.isEmpty(ships)) {
                throw Exceptions.bizException(ErrorCodes.ERROR_BIZ_SHIPPINGCOMPANY_REFED);
            }
        }
        dao.update("ShippingCompanyMapper.deleteByIds", ids);
        // 保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("DELETE_SHIPPINGCOMPANY", ids);
        PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_SHIPPINGCOMPANY, UserActions.DELETE, "删除航运公司",
                dataBackup);
    }

    @Override
    public ShippingCompanyDto findById(int id) {
        ParamData pd = new ParamData();
        pd.put("id", id);
        pd.put("language", PrincipalUtils.getLocalLanguage());
        ShippingCompany ship = (ShippingCompany) dao.findForObject("ShippingCompanyMapper.findById", pd);
        ShippingCompanyDto ShippingCompanyDto = new ShippingCompanyDto();
        BeanUtils.copyProperties(ship, ShippingCompanyDto);
        if (ShippingCompanyDto.getId() != null) {
            int refId = ShippingCompanyDto.getId();
            ParamData pdi18n = new ParamData();
            pdi18n.put("refId", refId);
            List<I18nDto> i18n = dao.findForList("ShippingCompanyMapper.findShipI18n", pdi18n, I18nDto.class);
            ShippingCompanyDto.setI18n(i18n);
            Country country = areaManager.findByCountryCode(ship.getCountryId());
            ShippingCompanyDto.setCountryName(country.getName());
        }
        return ShippingCompanyDto;
    }

    @Override
    public List<ShippingCompany> findByIds(List<Integer> ids) {
        ParamData pd = new ParamData();
        pd.put("list", ids);
        pd.put("language", PrincipalUtils.getLocalLanguage());
        return dao.findForList("ShippingCompanyMapper.findByIds", pd, ShippingCompany.class);
    }

    @Override
    public ResultDto findShippingCompanyListPage(QueryParams params) {
        String language = PrincipalUtils.getLocalLanguage();
        params.setLanguage(language);
        ParamData pd = this.convertQueryParams(params);
        // 调用方法查询数据
        List<ShippingCompany> list = dao.findForList("ShippingCompanyMapper.shippingCompanyListPage", pd, ShippingCompany.class);
        List<ShippingCompanyDto> dtos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(ship -> {
                ShippingCompanyDto dto = new ShippingCompanyDto();
                BeanUtils.copyProperties(ship, dto);
                Country country = areaManager.findByCountryCode(ship.getCountryId());
                dto.setCountryName(country.getName());
                dtos.add(dto);
            });
        }
        QResultDto dto = new QResultDto();
        dto.setData(dtos);
        dto.setPagination(pd.getPagination());
        return dto;
    }


    /**
     * 根据shipId查询航运公司信息
     *
     * @param ShipId ShipId
     * @return ShippingCompany
     */
    @Override
    public ShippingCompany findSimpleById(int ShipId) {
        ParamData pd = new ParamData();
        pd.put("id", ShipId);
        pd.put("language", PrincipalUtils.getLocalLanguage());
        return (ShippingCompany) dao.findForObject("ShippingCompanyMapper.findById", pd);
    }

    /**
     * 根据条件分页查询航运公司短接口
     *
     * @param params params
     * @return ResultDto
     */
    @Override
    public ResultDto findShippingCompanyShortListPage(QueryParams params) {
        String language = PrincipalUtils.getLocalLanguage();
        params.setLanguage(language);
        ParamData pd = this.convertQueryParams(params);
        // 调用方法查询数据
        List<ShippingCompany> list = dao.findForList("ShippingCompanyMapper.shippingCompanyShortListPage", pd, ShippingCompany.class);
        QResultDto dto = new QResultDto();
        dto.setData(list);
        dto.setPagination(pd.getPagination());
        return dto;
    }

    @Override
    public ResultDto findI18nByParam(QueryParams params) {
        ParamData pd = this.convertQueryParams(params);
        List entry = dao.findForList(getSqlName("findI18nByParamListPage"), pd, Map.class);
        return new QResultDto(entry, pd.getPagination());
    }

    /**
     * 航运公司名称校验
     *
     * @param name name
     * @param id   id
     */
    @Override
    public void checkShippingCompanyName(String name, Integer id) {
        checkName(name, id);
    }

    /**
     * 航运公司代码校验
     *
     * @param code code
     * @param id   id
     */
    @Override
    public void checkShippingCompanyCode(String code, Integer id) {
        checkCode(code, id);
    }

    @Override
    protected String getMapperNamespace() {
        return "ShippingCompanyMapper";
    }
}
